var http = {};
module.exports = http;

/**
 * 将URL中的参数字符串转成object
 */
var parseQueryString = function (queryStr) {
    if (!queryStr) { return {}; }
    queryStr = queryStr.split('?').pop();
    if (!queryStr) { return {}; }

    queryStr = decodeURIComponent(queryStr);

    var arrQuery = queryStr.split("&"), oQuery = {};
    for (var i = 0, ii = arrQuery.length; i < ii; i++) {
        var arrTmp = arrQuery[i].split("=");
        if (arrTmp.length === 2) {
            oQuery[arrTmp[0]] = arrTmp[1];
        }
    }
    return oQuery;
};

/**
 * 将object转成URL参数的格式
 */
var stringifyQueryString = function (params) {
    if (typeof params === 'string') {
        return params;
    } else if (params === null || typeof params !== 'object') {
        return encodeURIComponent(JSON.stringify(params));
    } else {
        var qs = '';
        for (var i in params) {
            if (params[i] !== undefined) {
                if (typeof params[i] === 'object') {
                    qs += '&' + i + '=' + encodeURIComponent(JSON.stringify(params[i]));
                } else {
                    qs += '&' + i + '=' + encodeURIComponent(params[i]);
                }
            }
        }
        return qs.slice(1);
    }
};

var bufferType = [
    'Blob',
    'ArrayBuffer',
    'Int8Array',        // 1byte  -128 to 127
    'Uint8Array',       // 1byte  0 to 255
    'Uint8ClampedArray',// 1byte  0 to 255
    'Int16Array',       // 2byte  -32768 to 32767
    'Uint16Array',      // 2byte  0 to 65535
    'Int32Array',       // 4byte  -2147483648 to 2147483647
    'Uint32Array',      // 4byte  0 to 4294967295
    'Float32Array',     // 4byte  1.2x10^-38 to 3.4x10^38
    'Float64Array',     // 8byte  5.0x10^-324 to 1.8x10^308
    'BigInt64Array',    // 8byte  -2^63 to (2^63)-1
    'BigUint64Array'    // 8byte  0 to (2^64)-1
]
var isBuffer = function (param) {
    var type = Object.prototype.toString.call(param).slice(8, -1);
    return bufferType.indexOf(type) > -1;
}

/**
 * 发文本、json、二进制
 * 收文本、json、二进制
 * @param {url:string, data:any, tamethod:'post'|'get', timeout:number, headers:object} option
 */
http.quest = function (option, callback) {
    // 请求类型
    var method = option.method || 'GET';
    // responseType
    var responseType = option.responseType || ''; //arraybuffer
    // 超时时间
    var timeout = option.timeout || 5000;
    // 请求头
    var headers = option.headers || { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" }; // application/json text/plain

    // 请求网址、数据、数据类型
    var url = '';
    var data = null;
    var buffer = false;
    if (method === 'post' || method === 'POST') {
        if (option.data) {
            url = option.url;
            data = option.data;
        } else {
            url = option.url.split('?')[0];
            data = parseQueryString(option.url);
        }
        buffer = isBuffer(data);
    } else {
        if (option.data) {
            url = option.url + '?' + stringifyQueryString(option.data);
        } else {
            url = option.url;
        }
    }

    // 请求实例
    var request = new XMLHttpRequest();
    request.open(method.toLocaleLowerCase(), url, true);

    // responseType 一般为'arraybuffer'或''
    if (responseType) request.responseType = responseType;

    // 设置请求头
    for (var key in headers) { request.setRequestHeader(key, headers[key]) }
    // 设置超时时间
    (timeout > 0) && (request.timeout = timeout);

    // 发送请求
    var needStringify = buffer ? false : (data !== null && typeof data !== 'string');
    request.send(needStringify ? JSON.stringify(data) : data);

    // request.onreadystatechange = () => {
    //     if (request.readyState == 4) {
    //         if (request.status >= 200 && request.status < 400) {
    //             if (responseType === 'arraybuffer') {
    //                 callback && callback(null, request.response);
    //             } else {
    //                 try {
    //                     callback && callback(null, JSON.parse(request.responseText), request.responseText, request.response);
    //                 } catch (e) {
    //                     callback && callback(null, request.responseText, request.responseText, request.response);
    //                 }
    //             }
    //         } else {
    //             callback && callback('status: ' + request.status, request.responseText);
    //         }
    //         callback = null;
    //     }
    // };

    // 进度
    // request.onprogress = function () {
    // }

    request.onload = function () {
        if (request.status >= 200 && request.status < 400) {
            if (responseType === 'arraybuffer') {
                callback && callback(null, request.response, request);
            } else {
                try {
                    callback && callback(null, JSON.parse(request.responseText), request);
                } catch (e) {
                    callback && callback(null, request.responseText, request);
                }
            }
        } else {
            callback && callback('status: ' + request.status, request.responseText, request);
        }
        callback = null;
    }

    request.ontimeout = function () {
        if (callback) {
            callback('timeout');
            callback = null;
            console.log('[http] %c连%c接%c超%c时 %s', 'color:red', 'color:orange', 'color:purple', 'color:green', url);
        }
    };
    request.onerror = function () {
        if (callback) {
            callback('error');
            callback = null;
            console.log('[http] %c连%c接%c失%c败 %s', 'color:red', 'color:orange', 'color:purple', 'color:green', url);
        }
    };
    request.onabort = function () {
        if (callback) {
            callback('abort');
            callback = null;
            console.log('[http] %c连%c接%c终%c止 %s', 'color:red', 'color:orange', 'color:purple', 'color:green', url);
        }
    };

    if (timeout) {
        setTimeout(() => {
            if (callback) {
                request.ontimeout();
                request.abort();
            }
        }, timeout);
    }
};
/**
 * http.get('login?code=asdi1239028sadadhjk213h', function(){})
 * http.get({url:'login', data:{code:'asdi1239028sadadhjk213h'}}, function(){})
 * http.get({url:'login', data:{code:'asdi1239028sadadhjk213h'}, responseType:'arraybuffer'}, function(){})
 * 
 */
http.get = function (url, callback, verification) {
    var option = url.url ? url : { url: url };
    option.method = 'get';
    option.isBuffer = false;
    this.quest(option, function (err, res) {
        if (!err && verification) {
            err = verification(res);
        }
        callback && callback(err, res);
    });
};
/**
 * http.post('login', function(){})
 * http.post('login?code=asdi1239028sadadhjk213h', function(){})
 * http.post({ url:'login', data:{code:'asdi1239028sadadhjk213h'} }, function(){})
 * http.post({ url:'login', data:{code:'asdi1239028sadadhjk213h'}, responseType:'arraybuffer' }, function(){})
 */
http.post = function (url, callback, verification) {
    var option = url.url ? url : { url: url };
    option.method = 'post';
    this.quest(option, function (err, res) {
        if (!err && verification) {
            err = verification(res);
        }
        callback && callback(err, res);
    });
};

/**
 * 加载二进制
 */
http.downloadBinary = function (url, callback) {
    var option = url.url ? url : { url: url };
    option.responseType = 'arraybuffer';

    this.get(option, function (err, res) {
        if (isBuffer(res)) res = new Uint8Array(res);
        callback && callback(err, res);
    });
}